package component

import (
	"fmt"
	"net/http"
)

// ServerResponse 表示后端服务(Dubbo/Http/gRPC/Echo)返回响应数据结构，
// 包含后端期望透传的状态码、Header和Attachment等数据
type (
	// ServerResponse 表示后端服务(Dubbo/Http/Echo)返回响应数据结构，
	ServerResponse struct {
		StatusCode  int                    // Http状态码
		Headers     http.Header            // Http Header
		Attachments map[string]interface{} // Attachment
		Data        interface{}            // 响应数据体
		Timestamp   int64                  // 响应时间戳
	}
	// ServerError 定义网关处理请求的服务错误
	ServerError struct {
		StatusCode int    // http status code
		ErrorCode  string // business error code
		Message    string // error message
		Cause      error  // 内部错误对象；错误对象不会被输出到请求端；
	}
	// ServerResponseWriter 用于解析和序列化响应数据结构的接口，并将序列化后的数据写入Http响应流。
	ServerResponseWriter interface {
		Write(ctx InnerContext, response *ServerResponse)
		WriteErr(ctx InnerContext, err *ServerError)
	}
)

var ResponseWriter ServerResponseWriter

func RegisterServerResponseWriter(writer ServerResponseWriter) {
	ResponseWriter = writer
}

func (e *ServerError) Error() string {
	if nil != e.Cause {
		return fmt.Sprintf("ServeError: StatusCode=%d, ErrorCode=%s, Message=%s, Error=%s", e.StatusCode, e.ErrorCode, e.Message, e.Cause)
	} else {
		return fmt.Sprintf("ServeError: StatusCode=%d, ErrorCode=%s, Message=%s", e.StatusCode, e.ErrorCode, e.Message)
	}
}

func NewServerError(statusCode int, errorCode string, message string) *ServerError {
	return &ServerError{
		StatusCode: statusCode,
		ErrorCode:  errorCode,
		Message:    message,
	}
}

func NewServerErrorWithCause(statusCode int, errorCode string, message string, cause error) *ServerError {
	return &ServerError{
		StatusCode: statusCode,
		ErrorCode:  errorCode,
		Message:    message,
		Cause:      cause,
	}
}
